using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;

public static class ControlExtensions
{
    /// <summary>
    /// Finds the control.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="control">The control.</param>
    /// <param name="id">The id.</param>
    /// <returns></returns>
    public static T FindControl<T>(this Control control, string id) where T : class
    {
        return control.FindControl(id) as T;
    }
    /// <summary>
    /// Finds the control.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="control">The control.</param>
    /// <param name="comparison">The comparison.</param>
    /// <returns></returns>
    public static T FindControl<T>(this Control control, Func<T, bool> comparison) where T : class
    {
        foreach (Control control2 in control.Controls)
        {
            T t = control2 as T;
            if (t != null && comparison(t))
            {
                T result = t;
                return result;
            }
            t = control2.FindControl(comparison);
            if (t != null)
            {
                T result = t;
                return result;
            }
        }
        return default(T);
    }
    /// <summary>
    /// Finds the control recursive.
    /// </summary>
    /// <param name="control">The control.</param>
    /// <param name="id">The id.</param>
    /// <returns></returns>
    public static Control FindControlRecursive(this Control control, string id)
    {
        foreach (Control control2 in control.Controls)
        {
            if (control2.ID != null && string.Equals(control2.ID, id, StringComparison.InvariantCultureIgnoreCase))
            {
                Control result = control2;
                return result;
            }
            Control control3 = control2.FindControlRecursive(id);
            if (control3 != null)
            {
                Control result = control3;
                return result;
            }
        }
        return null;
    }
    /// <summary>
    /// Finds the control recursive.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="control">The control.</param>
    /// <param name="id">The id.</param>
    /// <returns></returns>
    public static T FindControlRecursive<T>(this Control control, string id) where T : class
    {
        foreach (Control control2 in control.Controls)
        {
            if (control2.ID != null && string.Equals(control2.ID, id, StringComparison.InvariantCultureIgnoreCase) &&
                control2 is T)
            {
                T result = control2 as T;
                return result;
            }
            T t = control2.FindControlRecursive<T>(id);
            if (t != null)
            {
                T result = t;
                return result;
            }
        }
        return default(T);
    }
    /// <summary>
    /// Gets the parent.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="control">The control.</param>
    /// <returns></returns>
    public static T GetParent<T>(this Control control) where T : class
    {
        for (Control parent = control.Parent; parent != null; parent = parent.Parent)
        {
            if (parent is T)
            {
                return parent as T;
            }
        }
        return default(T);
    }
    /// <summary>
    /// Gets the type of the child controls by.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="control">The control.</param>
    /// <returns></returns>
    public static IEnumerable<T> GetChildControlsByType<T>(this Control control) where T : class
    {
        foreach (Control control2 in control.Controls)
        {
            if (control2 is T)
            {
                yield return control2 as T;
            }
        }
        yield break;
    }
    /// <summary>
    /// Sets the visibility.
    /// </summary>
    /// <param name="control">The control.</param>
    /// <param name="controls">The controls.</param>
    public static void SetVisibility(this Control control, params Control[] controls)
    {
        control.SetVisibility(true, controls);
    }
    /// <summary>
    /// Sets the visibility.
    /// </summary>
    /// <param name="control">The control.</param>
    /// <param name="visible">if set to <c>true</c> [visible].</param>
    /// <param name="controls">The controls.</param>
    public static void SetVisibility(this Control control, bool visible, params Control[] controls)
    {
        Array.ForEach<Control>(controls, delegate(Control c)
        {
            c.Visible = visible;
        }
        );
    }
    /// <summary>
    /// Sets the visibility.
    /// </summary>
    /// <param name="control">The control.</param>
    /// <param name="controlIDs">The control I ds.</param>
    public static void SetVisibility(this Control control, params string[] controlIDs)
    {
        control.SetVisibility(true, controlIDs);
    }
    /// <summary>
    /// Sets the visibility.
    /// </summary>
    /// <param name="control">The control.</param>
    /// <param name="visible">if set to <c>true</c> [visible].</param>
    /// <param name="controlIDs">The control I ds.</param>
    public static void SetVisibility(this Control control, bool visible, params string[] controlIDs)
    {
        for (int i = 0; i < controlIDs.Length; i++)
        {
            string id = controlIDs[i];
            Control control2 = control.FindControlRecursive(id);
            if (control2 != null)
            {
                control2.Visible = visible;
            }
        }
    }
    /// <summary>
    /// Sets the visibility.
    /// </summary>
    /// <param name="control">The control.</param>
    /// <param name="condition">The condition.</param>
    /// <param name="controls">The controls.</param>
    public static void SetVisibility(this Control control, Predicate<Control> condition, params Control[] controls)
    {
        Array.ForEach<Control>(controls, delegate(Control c)
        {
            c.Visible = condition(c);
        }
        );
    }
    /// <summary>
    /// Sets the visibility.
    /// </summary>
    /// <param name="control">The control.</param>
    /// <param name="condition">The condition.</param>
    /// <param name="controlIDs">The control I ds.</param>
    public static void SetVisibility(this Control control, Predicate<Control> condition, params string[] controlIDs)
    {
        for (int i = 0; i < controlIDs.Length; i++)
        {
            string id = controlIDs[i];
            Control control2 = control.FindControlRecursive(id);
            if (control2 != null)
            {
                control2.Visible = condition(control2);
            }
        }
    }
    /// <summary>
    /// Switches the visibility.
    /// </summary>
    /// <param name="control">The control.</param>
    /// <param name="visible">The visible.</param>
    /// <param name="notVisible">The not visible.</param>
    public static void SwitchVisibility(this Control control, Control visible, Control notVisible)
    {
        visible.Visible = true;
        notVisible.Visible = false;
    }

    public static T GetDataKeyValue<T>(this GridViewRow row)
    {
        GridView gv = row.NamingContainer as GridView;
        return (T)gv.DataKeys[row.RowIndex].Value;
    }
    public static object GetDataKeyValue(this GridViewRow row)
    {
        return GetDataKeyValue<object>(row);
    }
    public static object GetDataKeyValue(this GridViewRow row, string key)
    {
        return GetDataKeyValue<object>(row, key);
    }
    public static T GetDataKeyValue<T>(this GridViewRow row, string key)
    {
        GridView gv = row.NamingContainer as GridView;
        return (T)gv.DataKeys[row.RowIndex].Values[key];
    }
}
